﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using YJKRGeometry.CurveUtility;

namespace YJKArch.AxisModule
{
	public class DimensionPacker
	{
		public Dimension ThisDimension
		{
			get
			{
				return this.m_thisDimension;
			}
			private set
			{
				this.m_thisDimension = value;
			}
		}

		public Curve ThisDimensionLocationCurve
		{
			get
			{
				return this.m_thisDimensionLocationCurve;
			}
			private set
			{
				this.m_thisDimensionLocationCurve = value;
			}
		}

		public ReferenceArray ThisReferenceArray
		{
			get
			{
				return this.m_thisReferenceArray;
			}
			private set
			{
				this.m_thisReferenceArray = value;
			}
		}

		public Dictionary<int, Reference> DicNowReference
		{
			get
			{
				return this.m_dicNowReference;
			}
			private set
			{
				this.m_dicNowReference = value;
			}
		}

		public Dictionary<int, Curve> DicNowCurve
		{
			get
			{
				return this.m_dicNowCurve;
			}
			private set
			{
				this.m_dicNowCurve = value;
			}
		}

		public DimensionType ThisDimensionType
		{
			get
			{
				return this.m_thisDimensionType;
			}
			private set
			{
				this.m_thisDimensionType = value;
			}
		}

		public bool IfHasChanged
		{
			get
			{
				return this.m_bIfHasChanged;
			}
			private set
			{
				this.m_bIfHasChanged = value;
			}
		}

		public int ThisElementId
		{
			get
			{
				return this.m_thisElementId;
			}
			private set
			{
				this.m_thisElementId = value;
			}
		}

		public DimensionPacker(Dimension inputDimension)
		{
			this.m_thisDoc = inputDimension.Document;
			this.m_thisDimension = inputDimension;
			this.m_DimensionPackerUseView = inputDimension.View;
			this.ThisElementId = this.m_thisDimension.Id.IntegerValue;
			this.m_thisDimensionLocationCurve = this.m_thisDimension.Curve;
			this.m_thisReferenceArray = inputDimension.References;
			this.m_thisDimensionType = (this.m_thisDimension.Document.GetElement(this.m_thisDimension.GetTypeId()) as DimensionType);
			foreach (object obj in this.m_thisReferenceArray)
			{
				if (obj != null && obj is Reference && this.m_thisDoc.GetElement((obj as Reference).ElementId) is Grid)
				{
					Grid grid =  this.m_thisDoc.GetElement((obj as Reference).ElementId) as Grid;
					int integerValue = (obj as Reference).ElementId.IntegerValue;
					this.m_dicNowReference.Add(integerValue, obj as Reference);
					this.m_dicNowCurve.Add(integerValue, grid.Curve);
				}
			}
		}

		public bool TryReplaceOneId(int oldId, Reference newReference)
		{
			if (this.m_thisDoc.GetElement(new ElementId(oldId)) is MultiSegmentGrid)
			{
				foreach (ElementId elementId in (this.m_thisDoc.GetElement(new ElementId(oldId)) as MultiSegmentGrid).GetGridIds())
				{
					if (this.TryReplaceIfSame(elementId.IntegerValue, newReference))
					{
						return true;
					}
				}
				return false;
			}
			return this.TryReplaceOneIdBySingle(oldId, newReference);
		}

		private bool TryReplaceIfSame(int oldId, Reference newReference)
		{
			if (!this.m_dicNowReference.ContainsKey(oldId))
			{
				return false;
			}
			MultiSegmentGrid multiSegmentGrid = null;
			if (this.m_thisDoc.GetElement(newReference.ElementId) is MultiSegmentGrid)
			{
				multiSegmentGrid = (this.m_thisDoc.GetElement(newReference.ElementId) as MultiSegmentGrid);
			}
			if (multiSegmentGrid != null)
			{
				foreach (ElementId elementId in multiSegmentGrid.GetGridIds())
				{
					Curve curve = (this.m_thisDoc.GetElement(elementId) as Grid).Curve;
					if (CurveUtility.IsPointInCurve(this.m_dicNowCurve[oldId], curve.GetEndPoint(0), true) && CurveUtility.IsPointInCurve(this.m_dicNowCurve[oldId], curve.GetEndPoint(1), true))
					{
						this.m_dicNowReference[oldId] = new Reference(this.m_thisDoc.GetElement(elementId));
						this.IfHasChanged = true;
						return true;
					}
				}
				return false;
			}
			Curve curve2 = (this.m_thisDoc.GetElement(newReference.ElementId) as Grid).Curve;
			if (CurveUtility.IsPointInCurve(this.m_dicNowCurve[oldId], curve2.GetEndPoint(0), true) && CurveUtility.IsPointInCurve(this.m_dicNowCurve[oldId], curve2.GetEndPoint(1), true))
			{
				this.m_dicNowReference[oldId] = newReference;
				this.IfHasChanged = true;
				return true;
			}
			return false;
		}

		private bool TryReplaceOneIdBySingle(int oldId, Reference newReference)
		{
			if (!this.m_dicNowReference.ContainsKey(oldId))
			{
				return false;
			}
			this.m_dicNowReference[oldId] = newReference;
			this.IfHasChanged = true;
			return true;
		}

		public bool TryMakeNewDimension()
		{
			if (!this.IfHasChanged)
			{
				return true;
			}
			bool result;
			try
			{
				this.UpdataNowReferenceArray();
				Dimension thisDimension = this.ThisDimension;
				this.ThisDimension = this.m_thisDoc.Create.NewDimension(this.m_DimensionPackerUseView, this.ThisDimensionLocationCurve as Line, this.m_thisReferenceArray, this.ThisDimensionType);
				try
				{
					this.m_thisDoc.Delete(thisDimension.Id);
				}
				catch (Exception)
				{
				}
				result = true;
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}

		private void UpdataNowReferenceArray()
		{
			this.m_thisReferenceArray = new ReferenceArray();
			foreach (KeyValuePair<int, Reference> keyValuePair in this.m_dicNowReference)
			{
				this.m_thisReferenceArray.Append(new Reference(this.m_thisDoc.GetElement(keyValuePair.Value.ElementId)));
			}
		}

		private Document m_thisDoc;

		private Autodesk.Revit.DB.View m_DimensionPackerUseView;

		private int m_thisElementId;

		private Dimension m_thisDimension;

		private Curve m_thisDimensionLocationCurve;

		private ReferenceArray m_thisReferenceArray;

		private Dictionary<int, Reference> m_dicNowReference = new Dictionary<int, Reference>();

		private Dictionary<int, Curve> m_dicNowCurve = new Dictionary<int, Curve>();

		private DimensionType m_thisDimensionType;

		private bool m_bIfHasChanged;
	}
}
